#include "lvgl/lvgl.h"
#include "lvgl/demos/lv_demos.h"
#include "unistd.h"
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "main.h"

extern int usleep (__useconds_t __useconds);
extern int ping(const char *ips, double* delay);
extern void SocketInit();
extern const char* GetPingStr();
void UpdateInput(void);
void InitInput(void);

lv_obj_t * g_label1;
lv_obj_t * g_label2;
lv_display_t * g_disp;

void LvglDeployGRAM(void);
void MakeUpScrollDebugInfo(void);

static const char *getenv_default(const char *name, const char *dflt)
{
    return getenv(name) ? : dflt;
}

static void lv_linux_disp_init(void)
{
    const char *device = getenv_default("LV_LINUX_FBDEV_DEVICE", "/dev/fb0");
    g_disp = lv_linux_fbdev_create();

    lv_linux_fbdev_set_file(g_disp, device);
}

void ui_init(void)
{
    lv_init();

    /*Linux display device init*/
    lv_linux_disp_init();

	// displaysize : 800*480;
	// camera size : 640*480
    g_label1 = lv_label_create(lv_screen_active());
    lv_label_set_long_mode(g_label1, LV_LABEL_LONG_WRAP);     /*Break the long lines*/
    lv_label_set_text(g_label1, "Ping Server Init...");
    lv_obj_set_width(g_label1, 150);  /*Set smaller width to make the lines wrap*/
    lv_obj_set_style_text_align(g_label1, LV_TEXT_ALIGN_CENTER, 0);
    lv_obj_align(g_label1, LV_ALIGN_TOP_RIGHT, 0, 0);

	MakeUpScrollDebugInfo();
}

int ui_main(void)
{
	char str[128] = {0};
	SocketInit();
	InitInput();
    while(1) {
		struct timeval logTime[2];
		gettimeofday(&logTime[0], NULL);
		const char* targetIP = "192.168.3.33";
		double ms = 0.0;
		int ret = ping(targetIP, &ms);
		if (ret >= 0) {
			sprintf(str, "Ping %s\n in %.1fms", targetIP, ms);
		} else {
			sprintf(str, "Ping %s\nFailed:%d | %s", targetIP, ret, GetPingStr());
		}
		UpdateInput();
		LvglDeployGRAM();
    	lv_label_set_text(g_label1, str);
    	lv_label_set_text(g_label2, GetDebugStr());
		gettimeofday(&logTime[1], NULL);
		LOGScroll(4, "lvgl updated in %.3fms | debug height = %u", TimeDiffMillSec(logTime[1], logTime[0]), lv_obj_get_height(g_label2));
        lv_timer_handler();
    }

    return 0;
}

uint8_t g_lvglGram[CAPTURE_H][CAPTURE_W][3];
void LvglDrawPoint(int h, int w, uint8_t r, uint8_t g, uint8_t b)
{
	g_lvglGram[h][w][0] = r;
	g_lvglGram[h][w][1] = g;
	g_lvglGram[h][w][2] = b;
}

extern int frm_width, frm_height, fmt_type;
extern uint32_t* GetFbPtr(lv_display_t * disp);
void LvglDeployGRAM(void)
{
	uint32_t* pGRAM = GetFbPtr(g_disp);
	for (uint32_t h = 0; h < CAPTURE_H - lv_obj_get_height(g_label2) - 10; h++) {
		for (uint32_t w = 0; w < frm_width; w++) {
    		pGRAM[w + h * 800] = g_lvglGram[h][w][0] << 16 | g_lvglGram[h][w][1] << 8 | g_lvglGram[h][w][2];
		}
	}
}

void MakeUpScrollDebugInfo(void)
{
    static lv_style_t style;
    lv_style_init(&style);
    lv_style_set_bg_opa(&style, LV_OPA_COVER);
    lv_style_set_bg_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1));

    g_label2 = lv_label_create(lv_screen_active());
    lv_label_set_long_mode(g_label2, LV_LABEL_LONG_SCROLL_CIRCULAR);     /*Circular scroll*/
    lv_obj_set_width(g_label2, 700);
    lv_label_set_text(g_label2, "It is a circularly scrolling text. ");
    lv_obj_align(g_label2, LV_ALIGN_BOTTOM_LEFT, 15, 0);
    lv_obj_add_style(g_label2, &style, 0);
}